﻿using System;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using YXChatApiService.Application.AccountServices.Dtos;
using YXChatApiService.Core.AccountEntity;
using YXChatApiService.Core.AccountEntity.DomainManager;

namespace YXChatApiService.Application.AccountServices
{
    public class AccountAppService:IAccountAppService
    {
        private readonly IAccountManager _accountManager;
        private readonly IMapper _mapper;
        public AccountAppService(IAccountManager accountManager, IMapper mapper)
        {
            _accountManager = accountManager;
            _mapper = mapper;
        }
        public async Task<AccountDto> CreateOrUpdate(AccountEditDto input)
        {
            if (input.Id.HasValue)
            {
                return await Update(input);
            }
            else
            {
                return await Create(input);
            }
        }

        protected virtual async Task<AccountDto> Create(AccountEditDto input)
        {
            var oldAccount = _accountManager.QueryAsNoTracking.FirstOrDefault(n => n.PhoneNumber == input.PhoneNumber);
            if (oldAccount!=null)
            {
                return default;
            }
            var entity = _mapper.Map<Account>(input);
            entity.Id = Guid.NewGuid();
            entity.Avatar = "imgs/default.png";
            entity.CreateTime = DateTime.Now;
            entity.AccountNumber = CreateAccountNumber();
            await _accountManager.InsertAsync(entity);
            return _mapper.Map<AccountDto>(entity);
        }
        protected virtual async Task<AccountDto> Update(AccountEditDto input)
        {
            var entity = _mapper.Map<Account>(input);
            await _accountManager.UpdateAsync(entity);
            return _mapper.Map<AccountDto>(entity);
        }

        #region private

        private  string CreateAccountNumber()
        {
            while (true)
            {
                var accountNumber = DateTime.Now.Ticks.ToString().Substring(9);
                var entity = _accountManager.GetAccount(accountNumber);
                if (entity==null)
                {
                    return long.Parse(accountNumber).ToString();
                }
            }
        }

        #endregion
        public AccountDto GetAccount(string accountNumber)
        {
            var entity = _accountManager.GetAccount(accountNumber);
            return _mapper.Map<AccountDto>(entity);
        }
        public AccountDto Get(Guid id)
        {
            var entity = _accountManager.Get(id);
            return _mapper.Map<AccountDto>(entity);
        }

        public async Task<AccountDto> GetAccount(LoginInput input)
        {
            var entity= await _accountManager.QueryAsNoTracking
                .FirstOrDefaultAsync(n => n.AccountNumber == input.AccountNumber
                && n.PassWord == input.PassWord);
            return _mapper.Map<AccountDto>(entity);
        }
        public async Task UpdateAccountAvatar(string accountNumber,string imgUrl)
        {
            var entity = _accountManager.QueryAsNoTracking.FirstOrDefault(n => n.AccountNumber == accountNumber);
            if (entity != null)
            {
                entity.Avatar = imgUrl;
                await _accountManager.UpdateAsync(entity);
            }
        }

        public async Task<string> GetAccountPassWord(Guid id)
        {
            return (await _accountManager.QueryAsNoTracking.FirstOrDefaultAsync(x => x.Id.Equals(id))).PassWord;
        }
    }
}